package model;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * This class implementation has methods to detect all free positions corresponding to
 * a player in a particular grid configuration and return them accordingly.
 *
 */
public class LadderGridHelper
{
    /**
     * Returns a deep copy of the passed list.
     * 
     * @param grid
     * @return
     */
    public static ArrayList<ArrayList<GamePiece>> deepCopy(ArrayList<ArrayList<GamePiece>> grid)
    {
        ArrayList<ArrayList<GamePiece>> copy = new ArrayList<ArrayList<GamePiece>>(grid.size());
        for (int i = 0; i < grid.size(); i++)
        {
            ArrayList<GamePiece> rowCopy = (ArrayList<GamePiece>) grid.get(i).clone();
            copy.add(i, rowCopy);
        }

        return copy;
    }

    /**
     * Returns a list of all free slots available on the passed grid.
     * 
     * @param grid
     * @return
     */
    public static Set<Slot> getAllFreePositions(ArrayList<ArrayList<GamePiece>> grid)
    {
        Set<Slot> freePositions = new LinkedHashSet<Slot>();

        for (int i = 0; i < grid.size(); i++)
        {
            ArrayList<GamePiece> row = grid.get(i);
            for (int j = 0; j < row.size(); j++)
            {
                if (row.get(j) == GamePiece.NO_PIECE)
                {
                    freePositions.add(Slot.get(i, j));
                }
            }
        }

        return freePositions;
    }

    /**
     * Returns a list of all free slots adjacent to Occupied slots on the passed
     * grid.
     * 
     * @param grid
     * @return
     */
    public static Set<Slot> getAllFreePositionsAdjacentToOccupiedSlot(ArrayList<ArrayList<GamePiece>> grid)
    {
        Set<Slot> slots = new LinkedHashSet<Slot>();

        for (int i = 0; i < grid.size(); i++)
        {
            ArrayList<GamePiece> row = grid.get(i);
            for (int j = 0; j < row.size(); j++)
            {
                if (row.get(j) != GamePiece.NO_PIECE)
                {
                    for (Slot slot : Slot.get(i, j).getAllAdjacentSlot())
                    {
                        if (slot != null && grid.get(slot.getRowIndex()).get(slot.getColumnIndex()) == GamePiece.NO_PIECE)
                        {
                            slots.add(slot);
                        }
                    }
                }
            }
        }
        return slots;
    }
    
    public static boolean allPositionsAreFree(ArrayList<ArrayList<GamePiece>> grid)
    {
        for (int i = 0; i < grid.size(); i++)
        {
            ArrayList<GamePiece> row = grid.get(i);
            for (int j = 0; j < row.size(); j++)
            {
                if (row.get(j) != GamePiece.NO_PIECE)
                {
                    return false;
                }
            }
        }        
        return true;
    }
}
